/* 
 * File:   string.h
 * Author: bjorn
 *
 * Created on September 3, 2007, 9:03 PM
 */

#ifndef _ROPE_H
#define	_ROPE_H

#include <string>
#include <sstream>
#include <vector>
#include <map>
#include <list>

#include "object.h"
#include "memory.h"


typedef std::basic_string<char, std::char_traits<char>, std::allocator<char> >	Ropebase;

class 	Rope;
typedef Rope * Ropepointer;
/*
* Typedefs for convenience and to ease a possible later change of the back-end string type. 
*/

typedef std::list 	< Rope > 		Ropelinklist;
typedef std::vector < Rope > 		Ropelist;
typedef std::map	< Rope, Rope > 	Ropemap;


class Rope : public Ropebase {
	public : 
	Rope() : Ropebase() {
	}
	Rope(const Rope & rope ) : Ropebase(rope) {
	}
	Rope(const Ropebase & ropebase ) : Ropebase(ropebase) {
	}
	Rope(const char *str) : Ropebase(str) {
	}
	
	Ropelist split(const Rope & separator) const {
		Ropelist list;
		size_type lastpos = 0;
		size_type pos 	  = find(separator, lastpos);
		while(pos != npos) {
			Rope sub 	= substr(lastpos, pos - lastpos );
			list.push_back(sub);
			lastpos 	= pos + 1;
			pos 		= find(separator, lastpos);
		}
		Rope sub 	= substr(lastpos, size() - lastpos );
		list.push_back(sub);
		// Don't forget to put the last part of the string in the list.
		return list;
	}

	Ropelist split_any(const Rope & separators) const {
		Ropelist list;
		size_type lastpos = 0;
		size_type pos 	  = find_first_of(separators, lastpos);
		while(pos != npos) {
			Rope sub 	= substr(lastpos, pos - lastpos );
			list.push_back(sub);
			lastpos 	= pos + 1;
			pos 		= find_first_of(separators, lastpos);
		}
		Rope sub 	= substr(lastpos, size() - lastpos );
		list.push_back(sub);
		// Don't forget to put the last part of the string in the list.
		return list;
	}
	
	int utf8_next_index(int index) {
    	int result = 0;
    	unsigned char aid;
		// (unsigned char) 
    	aid = (*this)[index];
    	if (aid >= 0xF0)  	result++;
    	if (aid >= 0xE0) 	result++;
    	if (aid >= 0xC0) 	result++;
    	result++;
    	/* Skip the required amount of characters */
    	return result;
	}
	
	long utf8_decode_char(int index) {
		unsigned char c = (*this)[index];
	    if (c < 128) {
                return c;
        } else if((c > 191) && (c < 224)) {
                unsigned char c2 = (*this)[index+1];
                return (((c & 31) << 6) | (c2 & 63));
        } else {
				unsigned char c2 = (*this)[index+1];
				unsigned char c3 = (*this)[index+2];
                return (((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
        }
	}

	

}; 




int Rope_nextindex(Rope &str, int index);

/* A function which returns the index of the next unicode UTF-8 character
   in the UTF-8 Rope
*/

template < class Type >
inline Rope to_rope(const Type & value) {
    std::ostringstream stream;
    stream << value;
    return stream.str();
}



#endif	/* _ERUTA_STRING_H */
